package org.phalanx.gwt.client.screens;

import java.util.ArrayList;
import java.util.Iterator;

import org.phalanx.gwt.client.graphics.PhalanxGameMapView;
import org.phalanx.gwt.client.graphics.PhalanxGraphicsConsole;
import org.phalanx.gwt.client.graphics.PhalanxMapEventListener;
import org.phalanx.gwt.client.graphics.PhalanxWebMapView;
import org.phalanx.gwt.client.graphics.map.MapCoordinates;
import org.phalanx.gwt.client.graphics.map.MapTile;
import org.phalanx.gwt.client.graphics.map.MapTileSet;
import org.phalanx.gwt.client.graphics.map.PhalanxMap;
import org.phalanx.gwt.client.graphics.map.PhalanxMapReader;
import org.phalanx.gwt.client.graphics.map.PhalanxMapTerrain;
import org.phalanx.gwt.client.graphics.units.PhalanxMapUnit;
import org.phalanx.gwt.client.graphics.units.PhalanxMapUnitMatrix;
import org.phalanx.gwt.client.graphics.units.PhalanxMapUnitSet;
import org.phalanx.gwt.client.shared.MessageListener;
import org.phalanx.gwt.client.shared.MessageManager;
import org.phalanx.gwt.client.shared.OnLoadEvent;
import org.phalanx.gwt.client.shared.ServerMessage;
import org.phalanx.gwt.client.shared.WebPresentable;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class GameScreen implements PhalanxMapEventListener, MessageListener, ClickHandler, WebPresentable {
	MessageManager msgMgr;
	PhalanxMap pMap;
	PhalanxGameMapView mapView;
	PhalanxMapUnitSet uSet;
	private Button zoomIn = new Button("+");
	private Button zoomOut = new Button("-");
	private Label loadingLabel = new Label();

	public GameScreen(MessageManager msgMgr){
		this.msgMgr = msgMgr;
	}

	public void loadGameScreen(){
		// Request Map
		msgMgr.addMessageListener("mapdownload", this);
		msgMgr.addMessageListener("gamestate", this);

		ServerMessage msg = new ServerMessage();
		msg.setGET();
		msg.setContext("loadmap");
		msg.addMessageContents("mapname", "Ancient Greece");

		msgMgr.sendMessage(msg);
		createUSet();
	}

	private void createUSet(){
		uSet = new PhalanxMapUnitSet();
		uSet.addPhalanxMapUnit(new PhalanxMapUnit("INFANTRY", "INFANTRY"));
		uSet.addPhalanxMapUnit(new PhalanxMapUnit("VILLAGE", "VILLAGE"));
	}

	public void initialize(){
		mapView = new PhalanxGameMapView(pMap, new PhalanxMapUnitMatrix(pMap, uSet), 350, 700);

		/*mapView.getUnitMatrix().addUnitAt(new MapCoordinates(5,5), uSet.getMapUnit("VILLAGE"));
		mapView.getUnitMatrix().addUnitAt(new MapCoordinates(4,7), uSet.getMapUnit("INFANTRY"));

		for (int i = 4; i <= 6; i++){
			for (int j = 4; j <= 6; j++){
				mapView.setVisiblityToTable(new MapCoordinates(i,j));
			}
		}

		mapView.setVisiblityToTable(new MapCoordinates(4,7));*/
		mapView.setGameId(1000000);

		mapView.addPhalanxMapEventListener(this);
		mapView.addPresentationListener(this);

		VerticalPanel mapContainer = new VerticalPanel();

		zoomIn.addClickHandler(this);
		zoomOut.addClickHandler(this);

		mapContainer.add(mapView);
		mapContainer.add(loadingLabel);
		mapContainer.add(zoomIn);
		mapContainer.add(zoomOut);

		RootPanel.get("wartest").add(mapContainer);
		mapView.renderMap();

	}

	@Override
	public void onPhalanxMapTriggeredEvent(Event event, PhalanxGraphicsConsole source) {
		if (event.getTypeInt() == Event.ONCLICK){
			PhalanxGameMapView m = (PhalanxGameMapView)source;

			Integer xPos = m.getRelativePixelPositionX(event.getClientX());
			Integer yPos = m.getRelativePixelPositionY(event.getClientY());

			MapCoordinates c = m.getMapTilePosition(xPos, yPos);
			m.setCoordinates(c.getX(), c.getY());
			m.renderMap();
		}
	}

	@Override
	public void onMessageReceived(ServerMessage msg) {
		if (msg.getContext().equals("mapdownload")){
			PhalanxMapReader reader = new PhalanxMapReader();
			reader.setMapData(msg);
			pMap = reader.getMap();
			initialize();
		}
		else if (msg.getContext().equals("gamestate")){
			PhalanxMapUnitMatrix.getMatrixFromSerializedData(mapView.getUnitMatrix(), msg.getMessageContentsValue("gamestate"));
//			Window.alert(msg.getMessageContentsValue("gamestate"));
			
			ArrayList<MapCoordinates> fov = PhalanxMapUnitMatrix.getFOVfromSerializedData(msg.getMessageContentsValue("fov"));

			Iterator<MapCoordinates> i = fov.iterator();
			
			mapView.clearVisibilityTable();

			while (i.hasNext()){
				MapCoordinates c = i.next();
				
				mapView.setVisiblityToTable(c);
			}
			
			mapView.renderUnits();
		}
	}

	@Override
	public void onClick(ClickEvent event) {
		Double zoom = 0d;

		if (event.getSource().equals(zoomIn)){
			zoom = .5d;
		} else if (event.getSource().equals(zoomOut)){
			zoom = -.5d;
		}
		mapView.setZoomLevel(mapView.getZoomLevel() + zoom);
		mapView.renderMap();
	}

	@Override
	public void onContentLoaded(OnLoadEvent e) {
		if (e.getLoadContext().equals("rendermap")){
			loadingLabel.setText("Map Loaded");
		}
	}

	@Override
	public void onContentLoading(OnLoadEvent e) {
		if (e.getLoadContext().equals("rendermap")){
			loadingLabel.setText("Map Loading...");
		}
	}
}
